from django.shortcuts import render

# Create your views here.

import logging

from rest_framework.authentication import SessionAuthentication
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action

from course import models as course_models
from luffyapi.settings import contants

from django_redis import get_redis_connection
from redis import RedisError

logger = logging.getLogger('django')


class CartAPIView(ViewSet):

    permission_classes = [IsAuthenticated, ]

    def add(self, request):
        """将课程添加到购物车的接口"""
        course_id = request.data.get('course_id')

        # todo: user_id = request.user,id
        # 写一个假的用户 id 用来测试
        user_id = request.user.id

        # 有效期
        expire = 0  # 0 代表永久有效

        # 勾选状态
        is_selected = True

        # 判断课程是否存在
        try:
            course_models.Course.objects.get(pk = course_id)

        except course_models.Course.DoesNotExist:

            return Response({'msg': '商品不存在，请重新添加！'}, status=status.HTTP_400_BAD_REQUEST),

        # todo:判断此用户是否已经添加了这个课程
        try:
            redis_conn = get_redis_connection('cart')
            pipe = redis_conn.pipeline()
            pipe.multi()
            pipe.hset(f'cart_{user_id}', course_id, expire)
            pipe.sadd(f'selected_{user_id}', course_id)
            pipe.execute()

            # 获取购物车的商品的数量==字典中的键值对个数
            course_len = redis_conn.hlen(f'cart_{user_id}')
        except:
            logger.error('购物车添加失败')
            return Response({'mgs': '购物车添加失败'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

        return Response({'msg': '商品添加成功', 'course_len': course_len}, status=status.HTTP_201_CREATED)

    def cart_list(self, request):
        """获取购物车所有的课程数据的接口"""

        # user_id = request.user.id
        user_id = request.user.id
        redis_conn = get_redis_connection('cart')

        # 取出所有的课程数据
        cart_data_dict = redis_conn.hgetall(f'cart_{user_id}')

        # 获取所有的选中课程id
        selected_course_data = redis_conn.smembers(f'selected_{user_id}')
        data = []
        try:
            for course_id_bytes, expire_bytes in cart_data_dict.items():
                course_id = course_id_bytes.decode()
                expire_id = expire_bytes.decode()
                course_obj = course_models.Course.objects.get(pk=course_id)
                data.append(
                    {
                        'id': course_id,
                        'course_img': contants.SERVER_HOST + course_obj.course_img.url,
                        'name': course_obj.name,
                        'price': course_obj.price,
                        'real_price': course_obj.real_price(int(expire_id)),
                        'expire_id': int(expire_id),
                        'expire_list': course_obj.expire_list,
                        'is_selected': course_id_bytes in selected_course_data,
                    }
                )
        except:
            return Response({'msg': '获取课程失败'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({'msg': data}, status=status.HTTP_200_OK)

    # 切换购物车中选择购买课程的时间
    def change_course_selected(self, request):

        # 获取用户的id
        user_id = request.user.id

        # 获取用户所操作的课程
        course_id = request.data.get('course_id')
        is_selected = request.data.get('is_selected')

        try:
            course_models.Course.objects.get(pk=course_id)
        except course_models.Course.DoesNotExist:
            return Response({'msg': '商品不存在，请重新添加！'}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn = get_redis_connection('cart')

        if is_selected:
            redis_conn.sadd(f'selected_{user_id}', course_id)
        else:
            redis_conn.srem(f'selected_{user_id}', course_id)

        return Response({'msg': '勾选状态切换成功！'}, status=status.HTTP_200_OK)

    def change_expire(self, request):

        user_id = request.user.id
        course_id = request.data.get('course_id')
        expire_id = request.data.get('expire_id')
        try:
            course_obj = course_models.Course.objects.get(pk=course_id)

            # 永久有效的记录没有在course_expire这个表中，我们要先做排除
            if expire_id > 0:
                expire_obj = course_models.CourseExpire.objects.filter(is_show=True, is_deleted=False)
                if not expire_obj:
                    raise course_models.CourseExpire.DoesNotExist

                redis_conn = get_redis_connection('cart')
                redis_conn.hset(f'cart_{user_id}', course_id, expire_id)

        except course_models.CourseExpire.DoesNotExist:
            return Response({'msg': '有效期无效！'}, status=status.HTTP_400_BAD_REQUEST)
        except Exception:
            return Response({'msg': '服务器内部错误！'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        real_price = course_obj.real_price(expire_id)
        return Response({'msg': '切换有效期选项成功！', 'real_price': real_price}, status=status.HTTP_200_OK)

    @action(methods=['delete'], detail=True)
    def delete_course(self, request):

        # user_id = request.user.id
        user_id = request.user.id
        course_id = request.query_params.get('course_id')
        print('course_id', course_id, type(course_id))
        btn_ids = course_id.split(',')
        btn_ids = [int(x) for x in btn_ids if x.split()]
        buttons = course_models.Course.objects.filter(id__in=btn_ids)
        try:
            # course_models.Course.objects.get(pk=course_id)
            redis_conn = get_redis_connection('cart')
            pipe = redis_conn.pipeline()
            pipe.multi()
            for i in btn_ids:
                pipe.hdel(f'cart_{user_id}', i)
                pipe.srem(f'selected_{user_id}', i)
                # print(i)
            pipe.execute()
        except course_models.Course.DoesNotExist:
            return Response({'msg': '商品不存在，请重新添加'}, status=status.HTTP_400_BAD_REQUEST)
        except RedisError:
            return Response({'msg': "服务器内部错误"}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'msg': "删除商品成功"}, status=status.HTTP_204_NO_CONTENT)
